package archer.framework.utils;

import jodd.bean.BeanUtil;
import jodd.util.StringTemplateParser;

import java.util.Map;

/**
 * @author christ
 * @date 2016/7/6
 */
public class SmartString {

    private String template;

    public static SmartString template(String template) {
        return new SmartString(template);
    }

    protected SmartString(String template) {
        this.template = template;
    }

    /**
     * 绑定参数
     *
     * @param params
     * @return
     */
    public SmartString bind(Object... params) {

        if (ValidateUtils.isNotEmpty(params)) {
            for (int i = 0; i < params.length - 1; i++) {
                pipe(params[i]);
            }
            dest(params[params.length - 1]);
        }
        return this;
    }


    /**
     * 中间流程，不移除missingKey
     *
     * @param param
     * @return
     */
    private SmartString pipe(Object param) {

        if (param instanceof Map) {
            template = pipe.parse(template, createMapMacroResolver((Map) param));
        } else {
            template = pipe.parse(template, createEntityMacroResolver(param));
        }
        return this;
    }

    /**
     * 最终流程，会移除missingKey
     *
     * @param param
     * @return
     */
    private SmartString dest(Object param) {

        if (param instanceof Map) {
            template = dest.parse(template, createMapMacroResolver((Map) param));
        } else {
            template = dest.parse(template, createEntityMacroResolver(param));
        }
        return this;
    }

    public String toString() {
        return this.template;
    }

    //----------------------------inner-------------------------

    private static StringTemplateParser pipe;

    private static StringTemplateParser dest;

    static {
        pipe = new StringTemplateParser();
        pipe.setReplaceMissingKey(false);

        dest = new StringTemplateParser();
        dest.setReplaceMissingKey(true);
    }

    private static StringTemplateParser.MacroResolver createEntityMacroResolver(final Object entity) {

        return new StringTemplateParser.MacroResolver() {

            @Override
            public String resolve(String macroName) {
                Object value = BeanUtil.silent.getProperty(entity, macroName);
                if (value == null) {
                    return null;
                }
                return value.toString();
            }
        };
    }

    private static StringTemplateParser.MacroResolver createMapMacroResolver(final Map map) {
        return StringTemplateParser.createMapMacroResolver(map);
    }
}
